#ifndef CRCWORKER_H_
#define CRCWORKER_H_

#include "../util/Thread.h"
#include "CRCFinishListener.h"
#include "CRCBlocks.h"
#include "../util/BitStream.h"
#include "../util/Bits32Sequence.h"

using namespace ::miniprojeto::util;

namespace miniprojeto {
namespace Redundancy{
//! Thread que calcula o resto CRC de um bloco.
/*!
 * Esta classe é responsável pelo calculo do resto do CRC de uma bloco de 4KB. Deve ser fornecido
 * o bloco cujo calculo deve ser realizado e também uma instância de uma classe que implemente a
 * classe virtual pura CRCFinishListener. Esta unstância será notificada quando a CRCWorker
 * finalizar os cálculos.
 */
class CRCWorker : public Thread
{
protected:
	//! Código CRC de 17 bits que será utilizado nos cálculos.
	static Bits32Sequence* CRC;
	
	//! Bloco para o qual o resto CRC será calculado.
	CRCBlocks* block;
	
	//! Indice do CRCThread.
	int number;
	
	//! Instância de CRCFinishListener que será notificada.
	CRCFinishListener* finishListener;
	
	//! Conta o número de bits Zeros antes do bit 1 mais significativo
	/*!
		\param seq sequencia cujo bits zeros serão contados
		\return Número de zeros.
	*/
	int countZeros(Bits32Sequence* seq);
	
	//! Sobreescrita da função de Thread.
	virtual void run();
	
public:
	
	//! Construtor Padrão
	CRCWorker();
	
	//! Obtém o bloco de trabalho
	/*!
		\sa block
		\return block bloco para o qual foi calculado o CRC
	*/
	CRCBlocks* getCRCBlocks();
	
	//! Seta o bloco que será usado para o cálculo do CRC
	/*!
		\sa block
		\param block novo valor a ser atribuído a block
	*/
	void setCRCBlock(CRCBlocks* block);
	
	//! Adiciona uma instância que deve ser notificada ao termino da execução do Thread
	/*!
		\sa finishListener
		\param listener instância que será avisada
	*/
	void addFinishListener(CRCFinishListener* listener);
	
	//! Seta o indice da Thread
	/*!
		\sa number
		\param n novo indice da Thread
	*/
	void setNumber(int n);
	
	//! Destrutor
	virtual ~CRCWorker();
};

}
}

#endif /*CRCWORKER_H_*/